package battleship;

/**
 *
 * @author HUBERT Jean-Philippe <jean-philippe.hubert@uqac.ca>
 * UQAC - Université du Québec à Chicoutimi
 *
 */

/**
 * Cette classe est une amélioration de char[][] connaissanceAgent
 * Elle implémente en plus un int[][] stockant le numéro du tour de chaque case jouée
 *
 * Elle comporte des fonctions de recherches de dernier coup joué, de bateau...
 *
 * @author HUBERT Jean-Philippe <hubert.jeanphilippe@gmail.com>
 */

public class GrilleMemoire {
    private char[][] grilleCases;
    private int[][]  grilleNumeroTour;
    private int      i;
    private int      j;

    public GrilleMemoire() {
        initGrilleMemoire(10, 10);
    }

    public GrilleMemoire(int i, int j) {
        initGrilleMemoire(i, j);
    }

    private void initGrilleMemoire(int i, int j) {
        if ((i < 0) || (j < 0)) {
            throw new NegativeArraySizeException("Largeur/Longueur grilleMemoire négative -_-");
        }

        this.i                = i;
        this.j                = j;
        this.grilleCases      = new char[this.i][];
        this.grilleNumeroTour = new int[this.i][];

        for (int k = 0; k < this.i; k++) {
            this.grilleCases[k]      = new char[this.j];
            this.grilleNumeroTour[k] = new int[this.j];
        }


        // test de valeur par défaut
        if (grilleCases[0][0] == '\u0000') {
            System.out.println("Char init");
        }
    }

    public void MAJgrilleNumeroTour() {
        for (int k = 0; k < this.i; k++) {
            for (int l = 0; l < this.j; l++) {
                if (grilleCases[k][l] != 'v') {
                    grilleNumeroTour[k][l]++;
                }
            }
        }
    }


    /**
     * retourne le type de case aux coordonnées données en paramètre
     *
     * @param i
     * @param j
     * @return 
     */
    public char getCases(int i, int j) {
        if (((i < 0) && (i >= this.i)) && ((j < 0) && (j >= this.j))) {
            throw new ArrayIndexOutOfBoundsException("");
        }

        return this.getGrilleCases()[i][j];
    }

    /**
     * retourne le numero du tour de la case jouée aux coordonnées données en paramètre
     *
     * @param i
     * @param j
     * @return
     */
    public int getNumTourJoue(int i, int j) {
        if (((i < 0) && (i >= this.i)) && ((j < 0) && (j >= this.j))) {
            throw new ArrayIndexOutOfBoundsException("");
        }

        return this.getGrilleNumeroTour()[i][j];
    }

    /**
     * Modifie le type de case par la nouvelle valeur grilleCases aux coordonnées (i, j)
     * @param grilleCases
     * @param i
     * @param j
     */
    public void setCase(char grilleCases, int i, int j) {
        if (((i < 0) && (i >= this.i)) && ((j < 0) && (j >= this.j))) {
            throw new ArrayIndexOutOfBoundsException("");
        }

        this.getGrilleCases()[i][j] = grilleCases;
    }

    /**
     * Modifie le numero du tour de la case jouée par la nouvelle valeur grilleNumeroTour aux coordonnées (i, j)
     * @param grilleNumeroTour
     * @param i
     * @param j
     */
    public void setNumeroTourCase(int grilleNumeroTour, int i, int j) {
        if (((i < 0) && (i >= this.i)) && ((j < 0) && (j >= this.j))) {
            throw new ArrayIndexOutOfBoundsException("-_-");
        }

        this.getGrilleNumeroTour()[i][j] = grilleNumeroTour;
    }

    /**
     *
     * @return La grille des types de cases
     */
    public char[][] getGrilleCases() {
        return grilleCases;
    }

    /**
     *
     * @return La grille des numeros de tour des cases jouées.
     */
    public int[][] getGrilleNumeroTour() {
        return grilleNumeroTour;
    }

    /**
     * Modificateur par copie de la grille des types de cases
     * @param grilleCases
     */
    public void setGrilleCases(char[][] grilleCases) {
        boolean ok = false;

        if (grilleCases.length == this.grilleCases.length){
            for (int k=0;j<grilleCases.length;k++){
                if (grilleCases.length == grilleCases.length)
                    ok = true;
                else
                    ok = false;

                if (!ok)
                    break;
            }
        }

        for (int l = 0;l<grilleCases.length;l++){
            for (int k = 0;k<grilleCases[l].length;k++){
                this.grilleCases[l][k] = grilleCases[l][k];
            }
        }
    }

    /**
     * Modificateur par copie de la grille des numeros des tours des cases jouées
     * @param grilleNumeroTour
     */
    public void setGrilleNumeroTour(int[][] grilleNumeroTour) {
        this.grilleNumeroTour = grilleNumeroTour;
    }

    /**
     * Existance d'une coup joué sur bateau de type c il y a numTour tours.
     *
     * @param c code du bateau recherché
     * @param numTour numero du tour auquel le bateau a été touché
     * @return vrai si la case a été trouvée faux sinon
     */
    public boolean chercheCase(char c, int numTour){
        boolean ok = false;
        if (numTour<=0)
            return ok;
        for (int k=0;k<grilleCases.length;k++){
            for(int l=0;l<grilleCases[k].length;l++){
                if (grilleNumeroTour[k][l] == numTour && grilleCases[k][l] == c){
                    ok = true;
                }
            }
        }
        return ok;
    }


    /**
     *
     * @param numTour numéro du tour auquel le coup a été joué
     * @return vrai si la case a été trouvée, faux sinon
     */
    public boolean chercheCaseTouche(int numTour){
        return this.chercheCase('f', numTour)
                || this.chercheCase('g', numTour)
                || this.chercheCase('h', numTour)
                || this.chercheCase('i', numTour)
                || this.chercheCase('j', numTour);
    }

    /**
     * Recherche de la derniere case jouee
     *
     * @return int[] si les coordonnees ont ete trouves, null sinon.
     */
    public int[] derniereCase(){
        int[] coord = new int[2];

        for (int k=0;k<grilleNumeroTour.length;k++){
            for (int l=0;l<grilleNumeroTour[k].length;l++){
                 if (grilleNumeroTour[k][l] == 1){
                     coord[0] = k;
                     coord[1] = l;
                     return coord;
                 }
            }
        }
        return null;
    }
    /**
     *
     * @param bateau code du bateau recherché
     * @return coordonnées du bateau recherché
     */
    public int[] chercheBateau(char bateau){
        for (int k=0;k<this.grilleCases.length;k++){
            for (int l=0;l<this.grilleCases.length;l++){
                if (this.grilleCases[k][l] == bateau) {
                    int[] coord = new int[2];
                    coord[0] = k;
                    coord[1] = l;
                    return coord;
                }
            }
        }

        return null;
    }

    /**
     * 
     * @return numéro du bateau touché lors du dernier coup joué
     */
    public int numBateauDerniereCase(){
        int[] coord = derniereCase();
        char bateau = this.grilleCases[coord[0]][coord[1]];
        switch(bateau){
            case 'f':
                return 0;
            case 'g':
                return 1;
            case 'h':
                return 2;
            case 'i':
                return 3;
            case 'j':
                return 4;
            default:
                return -1;
        }
    }

    /**
     * Seulement pour afficher en console
     *
     */
    public void print(){
        System.out.println();
        System.out.println("________________________________________________________");
        for (int k = 0 ; k < grilleNumeroTour.length ; k++){
            System.out.print("||");
            for (int l = 0 ; l < grilleNumeroTour[k].length ; l++){
                if (grilleCases[k][l] == '\u0000') {
                    grilleCases[k][l] = '_';
                }
                System.out.print("  "+grilleCases[k][l] + "/" + grilleNumeroTour[k][l]);
            }
            
           System.out.println("  ||");
        }
    }
}
